package managedBean;

import Merlion.userManagement.bean.CurrentSessionBeanRemote;
import Merlion.userManagement.bean.LoginBeanRemote;
import Merlion.userManagement.bean.RegistrationBeanRemote;
import Merlion.userManagement.bean.ResetPasswordBeanRemote;
import Merlion.util.helper.PasswordHash;
import Merlion.util.state.SystemUserState;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseEvent;
import org.hibernate.validator.constraints.impl.EmailValidator;
import org.primefaces.event.IdleEvent;
import Merlion.userManagement.entity.RoleEntity;
import Merlion.userManagement.entity.SystemUserEntity;

@ManagedBean(name = "UserManagedBean")
@ViewScoped
public class UserManagedBean {

    private String email;
    private String name;
    private String password;
    private String confirmPassword;
    private List<String> roles;
    private String securityQuestion;
    private String securityAnswer;
    private String address;
    private String phoneNumber;
    private String gender;
    private String city;
    private String country;
    private String status;
    private boolean loginStatus;
    private boolean lockStatus;
    private String selectedRole;
    
    private List<SystemUserState> userList;
    private SystemUserEntity user = new SystemUserEntity();
  
    @EJB
    private RegistrationBeanRemote registrationBean;
    @EJB
    private LoginBeanRemote loginBean;
    @EJB
    private ResetPasswordBeanRemote resetPasswordBean;
    @EJB
    private CurrentSessionBeanRemote currentSessionBean;

    public UserManagedBean() {
    }

    public void initView(PhaseEvent event){
       FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        userList = registrationBean.viewAllUser();
    }
    
    
    public void doRegister(ActionEvent event) throws IOException {
        try {
            System.out.println("**UserManagedBean: doRegister()");

            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("email", email);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("name", name);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("password", password);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("address", address);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("phoneNumber", phoneNumber);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("gender", gender);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("city", city);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("country", country);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("roles", roles);

            currentSessionBean.setCurrentRegistrationId(email);
           
            boolean regStatus = registrationBean.createNewUser(email, name, password, roles, address, phoneNumber, gender, city, country, null, null);
            
            if (regStatus = true) {             
                System.out.println("**UserManagedBean: Registration of user " + email + " is successful.");
                FacesContext.getCurrentInstance().getExternalContext().redirect("SuccessfulRegistration.xhtml");
            } else {
                System.out.println("**UserManagedBean: Registration of user " + email + " failed.");
                FacesContext.getCurrentInstance().getExternalContext().redirect("FailRegistration.xhtml");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void doLogin(ActionEvent event) {
        try {
            System.out.println("**UserManagedBean: doLogin()");
            loginStatus = loginBean.tryLogin(email, password);
            System.out.println("**UserManagedBean: loginStatus is " + loginStatus);

            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("email", email);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("password", password);
 
            if (loginStatus == true) {
                System.out.println("**UserManagedBean: Login is successful.");
                System.out.println("**UserManagedBean: redirecting to role option page...");
                roles = loginBean.getRoles(email);
                for(Object o : roles){
                    String a = (String) o;
                    System.out.println(a);
                }
                FacesContext.getCurrentInstance().getExternalContext().getFlash().put("roles", roles);
                currentSessionBean.setCurrentId(email);
                currentSessionBean.setCurrentRole(selectedRole);
                System.out.println(selectedRole);
                FacesContext.getCurrentInstance().getExternalContext().redirect("https://localhost:8181/MerlionERP-war/userManagement/ChooseRole.xhtml");
                
            } else {
                System.out.println("**UserManagedBean: Login failed.");
                FacesContext.getCurrentInstance().getExternalContext().redirect("https://localhost:8181/MerlionERP-war/userManagement/FailLogin.xhtml");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void doRedirectRole(ActionEvent event) {
        try {
            if (selectedRole.equalsIgnoreCase("Customer Executive")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("../CRM/SalesDeptWorkspace.xhtml");
            } else if (selectedRole.equalsIgnoreCase("Finance Executive")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("../FRM/FinanceDeptWorkspace.xhtml");
            } else if (selectedRole.equalsIgnoreCase("Production Executive")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("../MRP/ManufacturingDeptWorkspace.xhtml");
            } else if (selectedRole.equalsIgnoreCase("Supply Chain Executive")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("../SCM/InventoryDeptWorkspace.xhtml");
            } else if (selectedRole.equalsIgnoreCase("Customer Executive Manager")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("../CRM/SalesDeptWorkspace.xhtml");
            } else if (selectedRole.equalsIgnoreCase("Finance Executive Manager")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("../FRM/FinanceDeptWorkspace.xhtml");
            } else if (selectedRole.equalsIgnoreCase("Production Executive Manager")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("../MRP/ManufacturingDeptWorkspace.xhtml");
            } else if (selectedRole.equalsIgnoreCase("Supply Chain Executive Manager")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("../SCM/InventoryDeptWorkspace.xhtml");
            } else if (selectedRole.equalsIgnoreCase("Technical Support Executive")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("AdminDeptWorkspace.xhtml");
            } else if (selectedRole.equalsIgnoreCase("President")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("PresidentWorkspace.xhtml");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public void doLogout(ActionEvent event) {
        try {
            System.out.println("**UserManagedBean: doLogout()");
            email = currentSessionBean.getCurrentId();
            loginBean.tryLogout(email);
            System.out.println("**UserManagedBean: Logout is successful.");
            FacesContext.getCurrentInstance().getExternalContext().redirect("https://localhost:8181/MerlionERP-war/userManagement/index.xhtml");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void doActivate(ActionEvent event) {
        try {
            System.out.println("**UserManagedBean: doActivate()");

            boolean activationStatus = loginBean.activateAccount(email);  
            
            if (activationStatus == true) {
                resetPasswordBean.changeSecurityQuestion(email, securityQuestion, securityAnswer);
                FacesContext.getCurrentInstance().getExternalContext().getFlash().put("email", email);
                System.out.println("**UserManagedBean: Account activation is successful.");
                FacesContext.getCurrentInstance().getExternalContext().redirect("SuccessfulActivation.xhtml");
            } else {
                FacesContext.getCurrentInstance().getExternalContext().getFlash().put("email", email);
                System.out.println("**UserManagedBean: Account activation failed.");
                FacesContext.getCurrentInstance().getExternalContext().redirect("FailActivation.xhtml");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void doGetSecurityQuestion(PhaseEvent event) {
        try {
            System.out.println("**UserManagedBean: doGetSecurityQuestion()");
            email = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("email");
            
            securityQuestion = resetPasswordBean.getSecurityQuestion(email);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("securityQuestion", securityQuestion);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("email", email);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void doGetPassword(PhaseEvent event) {
        try {
            System.out.println("**UserManagedBean: doGetPassword()");
            email = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("email");
            
            String actualPassword = resetPasswordBean.getPassword(email);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("actualPassword", actualPassword);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("email", email);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public void doResetPassword(ActionEvent event) {
        try {
            System.out.println("**UserManagedBean: doResetPassword()");
            email = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("email");
            securityQuestion = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("securityQuestion");
            String actualSecurityAnswer = resetPasswordBean.getSecurityAnswer(email);
            
            if (password.equalsIgnoreCase(confirmPassword)  && securityAnswer.equalsIgnoreCase(actualSecurityAnswer)) {
                boolean resetStatus = resetPasswordBean.updatePassword(email, password, securityAnswer);
                
                if (resetStatus == true) {
                    System.out.println("**UserManagedBean: Reset password successfully.");
                    FacesContext.getCurrentInstance().getExternalContext().redirect("SuccessfulResetPassword.xhtml");
                } else {
                    System.out.println("**UserManagedBean: Fail to reset password.");               
                    FacesContext.getCurrentInstance().getExternalContext().redirect("FailResetPassword.xhtml");
                }
            } else {
                System.out.println("**UserManagedBean: Fail to reset password.");               
                FacesContext.getCurrentInstance().getExternalContext().redirect("FailResetPassword.xhtml");  
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void submitNameForPasswordReset(ActionEvent event) throws IOException {
        System.out.println("**UserManagedBean: submitNameForPasswordReset()");
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("email", email);
        FacesContext.getCurrentInstance().getExternalContext().redirect("ResetPassword2.xhtml");
    }
    
    public void submitNameForChangeSecurity(ActionEvent event) throws IOException {
        System.out.println("**UserManagedBean: submitNameForChangeSecurity()");
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("email", email);
        FacesContext.getCurrentInstance().getExternalContext().redirect("ChangeSecurity2.xhtml");
    }

    public void doChangeSecurity(ActionEvent event) {
        try {
            System.out.println("**UserManagedBean: doChangeSecurity()");
            email = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("email");
            String actualPassword = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("actualPassword");
            boolean changeStatus = false;
            
            if (PasswordHash.MD5(password + email).equals(actualPassword)) {
                changeStatus = resetPasswordBean.changeSecurityQuestion(email, securityQuestion, securityAnswer);
                
                if (changeStatus == true) {
                    System.out.println("**UserManagedBean: Change security question successfully.");
                    FacesContext.getCurrentInstance().getExternalContext().redirect("SuccessfulChangeSecurity.xhtml");
                } else {
                    System.out.println("**UserManagedBean: Fail to change security question.");               
                    FacesContext.getCurrentInstance().getExternalContext().redirect("FailChangeSecurity.xhtml");
                }
            } else {
                System.out.println("**UserManagedBean: Fail to change security question.");               
                FacesContext.getCurrentInstance().getExternalContext().redirect("FailChangeSecurity.xhtml");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    //now assume using gmail, live, hotmail,yahoo
    public void validateEmail(FacesContext context, UIComponent toValidate, Object value) {
        String email = (String) value;

        if ((email.indexOf('@') == -1)
                || ((!email.contains(".com")) && (!email.contains(".co.")))
                || ((!email.contains("yahoo")) && (!email.contains("gmail")) && (!email.contains("hotmail"))
                && (!email.contains("live")))) {
            ((UIInput) toValidate).setValid(false);
            FacesMessage message = new FacesMessage("Invalid Email Address (gmail,hotmail,live, and yahoo)");
            context.addMessage(toValidate.getClientId(context), message);
        }
    }

    public RegistrationBeanRemote getRegistrationBean() {
        return registrationBean;
    }

    public void setRegistrationBean(RegistrationBeanRemote registrationBean) {
        this.registrationBean = registrationBean;
    }

    public LoginBeanRemote getLoginBean() {
        return loginBean;
    }

    public void setLoginBean(LoginBeanRemote loginBean) {
        this.loginBean = loginBean;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getConfirmPassword() {
        return confirmPassword;
    }

    public void setConfirmPassword(String confirmPassword) {
        this.confirmPassword = confirmPassword;
    }

    public List<String> getRoles() {
        return roles;
    }

    public void setRoles(List<String> roles) {
        this.roles = roles;
    }

    public String getSecurityQuestion() {
        return securityQuestion;
    }

    public void setSecurityQuestion(String securityQuestion) {
        this.securityQuestion = securityQuestion;
    }

    public String getSecurityAnswer() {
        return securityAnswer;
    }

    public void setSecurityAnswer(String securityAnswer) {
        this.securityAnswer = securityAnswer;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public boolean isLoginStatus() {
        return loginStatus;
    }

    public void setLoginStatus(boolean loginStatus) {
        this.loginStatus = loginStatus;
    }

    public CurrentSessionBeanRemote getCurrentSessionBean() {
        return currentSessionBean;
    }

    public void setCurrentSessionBean(CurrentSessionBeanRemote currentSessionBean) {
        this.currentSessionBean = currentSessionBean;
    }

    public boolean isLockStatus() {
        return lockStatus;
    }

    public void setLockStatus(boolean lockStatus) {
        this.lockStatus = lockStatus;
    }

    public ResetPasswordBeanRemote getResetPasswordBean() {
        return resetPasswordBean;
    }

    public void setResetPasswordBean(ResetPasswordBeanRemote resetPasswordBean) {
        this.resetPasswordBean = resetPasswordBean;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public SystemUserEntity getUser() {
        return user;
    }

    public void setUser(SystemUserEntity user) {
        this.user = user;
    }

    public List<SystemUserState> getUserList() {
        return userList;
    }

    public void setUserList(List<SystemUserState> userList) {
        this.userList = userList;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSelectedRole() {
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        System.out.println("Get selected role: "+selectedRole);
        return selectedRole;
    }

    public void setSelectedRole(String selectedRole) {
        System.out.println("SET SELECTED ROLE");
        this.selectedRole = selectedRole;
    }
    
    public String redirectToResetPassword(){
        return "success";
        /*System.out.println("REDIRECT TO RESET PASSWORD");
        try {
            FacesContext.getCurrentInstance().getExternalContext().redirect("ResetPassword.xhtml");
        } catch (IOException ex) {
            ex.printStackTrace();
        }*/
    }

    public String redirectToChangeSecurity(){
        return "success";
        /*System.out.println("REDIRECT TO CHANGE SECURITY");
        try {
            FacesContext.getCurrentInstance().getExternalContext().redirect("ChangeSecurity.xhtml");
        } catch (IOException ex) {
            ex.printStackTrace();
        }*/
    
    }
}

